#!/usr/bin/env python
# coding=utf-8
##from Src.tracker.spiders.auspost import types_track

from vavava.dbhelper import _dbhelper
import time

class TrackStatus:
    def __init__(self,datalist=[]):
        self.shipment_iD     = datalist[0]
        self.track_type      = datalist[1]
        self.shipment_name   = datalist[2]
        self.shipment_status = datalist[3]
        self.create_time     = datalist[4]
        self.modify_time     = datalist[5]

class TrackData:
    """ Tracking summary """
    def __init__(self, track_type=-1, name="", track_time=None, description="",
                 location="", shipment_id=-1, created=None, id=-1 ):
        self.ID          = id
        self.track_type  = track_type
        self.name        = name
        self.track_time  = track_time
        self.description = description
        self.location    = location
        self.shipment_id = shipment_id
        self.created     = created
        self.is_ended    = 0

    @staticmethod
    def GetInstance(db_data):
        item = TrackData()
        item.id          = db_data[0]
        item.track_type  = db_data[1]
        item.name        = db_data[2]
        item.track_time  = db_data[3]
        item.description = db_data[4]
        item.location    = db_data[5]
        item.shipment_id = db_data[6]
        item.created     = db_data[7]
        return item

    def __hash__(self):
        key = "%s%d%s%s%s"%(
            self.name,
            self.track_type,
            self.track_time,
            self.description,
            self.location
            )
        return key.__hash__()

    def __eq__(self, other):
        """ define for dic key """
        return self.name == other.name\
               and self.trackTime   == other.track_time\
               and self.track_type  == other.track_type\
               and self.description == other.description\
               and self.location    == other.location

ITEM_RETRY_OUT = 10
class TrackDB(_dbhelper):
    def __init__(self,db_conn=None,log=None):
        _dbhelper.__init__(self,db_conn,log)

    def __del__(self):
        if self.cursor:
            self.cursor.close()

    def init_db_cursor(self,conn):
        self._init_cursor(conn)

    def sp_insert_new_item(self, track_type, is_ended,name, trackTime, description, location):
        """  insert a new track data  """
        try:
            self.conn.begin()
            track_time = trackTime.strftime("%Y-%m-%d %H:%M:%S")
            result = self.cursor.callproc( "sp_insert_track_item",
                           [ track_type, str(is_ended).lower(), name, track_time, description, location ] )
            self.conn.commit()
            res = 0
            n = self.cursor.execute("select @result_")
            res = self.cursor.fetchone()
            if res:
                return res[0]
            else:
                return res
        except Exception as e:
            self.log.exception(e)
            self.conn.rollback()

    def sp_update_item_status(self,track_type, name, retry_timeout=True):
        """insert or update a track status"""
        try:
            self.conn.begin()
            flag = 0
            if retry_timeout:
                flag = 1
            result = self.cursor.callproc( "sp_update_track_item_status", [ track_type, name, flag ] )
            self.conn.commit()
            res = 0
            n = self.cursor.execute("select @timeout_count_")
            res = self.cursor.fetchone()
            return res
        except Exception as e:
            self.log.exception(e)
            self.conn.rollback()

    def get_tracking_items(self, track_type):
        return self._get_item_list_by_sql(
            r'select * from track_status where tracktype_id=%d and shipment_status >= 0 and shipment_status < %d'
            % (track_type,ITEM_RETRY_OUT)
        )

    def get_delivered_items(self, track_type):
        return self._get_item_list_by_sql(
            r'select * from track_status where tracktype_id=%d and shipment_status = -1' % track_type
        )

    def get_timeout_items(self, track_type):
        return self._get_item_list_by_sql(
            r'select * from track_status where tracktype_id=%d and shipment_status = -2 or shipment_status >= %d'
            % (track_type,ITEM_RETRY_OUT)
        )

    def item_get_top10(self,item,track_type):
        bt=time.clock()
        sql = r"select * from track_data where tracktype_id=%d and name = '%s' order by tracktime desc limit 10"\
              % (track_type,item)
        n = self.cursor.execute(sql)
        re_dict={}
        for i in range(n):
            db_data = self.cursor.fetchone()
            db_item = TrackData.GetInstance(db_data)
            re_dict[db_item] = ""
        interval = time.clock()-bt
        self.log.debug("interval:item_get_top10(%s,%d) %f" % (item,len(re_dict),interval) )
        return re_dict

    def _get_item_list_by_sql(self,sql):
        bt=time.clock()
        n = self.cursor.execute(sql)
        res = self.cursor.fetchall()
        res_dict = {}
        for each in res:
            if len(each) > 2:
                ts = TrackStatus(each)
                res_dict[ts.shipment_name] = ts
            else:
                self.log.error( "result:%d" % len(each) )
        interval = time.clock()-bt
        self.log.debug("interval:_get_item_list_by_sql %f" % interval)
        return res_dict

    def sp_log(self,msg,remark=""):
        try:
            result = self.cursor.callproc( "_log", [ msg,remark ] )
        except Exception as e:
            self.log.exception(e)

    def sp_init_test_data(self):
        try:
            result = self.cursor.callproc( "sp_init_test_data", [ ] )
        except Exception as e:
            self.log.exception(e)












